package com.ocm.core.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ocm.core.dao.StorageDao;
import com.ocm.core.domain.ClassDefinition;
import com.ocm.core.domain.Storage;
import com.ocm.core.dto.StorageDto;
import com.ocm.core.helper.StorageHelper;
import com.ocm.core.mapping.DTOConfiguration;
import com.ocm.core.mapping.DTOService;
import com.ocm.core.mapping.DomainService;
import com.ocm.core.model.ClassInstance;
import com.ocm.core.service.OCMService;
import com.ocm.core.service.StorageService;

@Service("storageService")
@Transactional(readOnly = true)
public class StorageServiceImpl implements StorageService {

   private StorageDao storageDao;

   private DomainService domainService;

   private DTOService dtoService;

   private OCMService ocmService;

   @Autowired
   private StorageHelper storageHelper;

   @Autowired
   public StorageServiceImpl(
         @Qualifier("storageDao")StorageDao storageDao, 
         @Qualifier("ocmService")OCMService ocmService,
         @Qualifier("domainService")DomainService domainService, 
         @Qualifier("dtoService")DTOService dtoService) {
      this.storageDao = storageDao;
      this.ocmService = ocmService;
      this.domainService = domainService;
      this.dtoService = dtoService;
   }

   @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
   public void create(StorageDto storageDto) {
      Storage storage = this.domainService.convertStorage(storageDto);
      this.storageHelper.setUserInfo(storage);
      List<ClassDefinition> classDefs = this.storageHelper.getClassDefsDefault(storage);
      try {
         ClassInstance classInstance = this.ocmService.createStorage(storage);
         storage.setStorageUID(classInstance.getNodeUUID());
         storage.setRealPath(classInstance.getRealPath());
         for (ClassDefinition classDefinition : classDefs){
            this.storageHelper.setUserInfo(classDefinition);
            classInstance = this.ocmService.createClassDefintion(classDefinition);
            classDefinition.setClassDefUID(classInstance.getNodeUUID());
            classDefinition.setRealPath(classInstance.getRealPath());
         }
         storage.setClassDefs(classDefs);
         this.storageDao.save(storage);
      } catch (Exception e){
         for (ClassDefinition classDefinition : classDefs){
            this.ocmService.createClassDefintion(classDefinition);
         }
      }
   }


   public List<StorageDto> findAll(DTOConfiguration configuration) {
      List<Storage> storages = this.storageDao.findAll();
      List<StorageDto> storageDtos = new ArrayList<StorageDto>();
      for (Storage storage : storages) {
         storageDtos.add(this.dtoService.convertStorageDto(storage, configuration));
      }
      return storageDtos;
   }

   public boolean hasExistName(String storageName) {
      Storage storage = this.storageDao.findName(storageName);
      if (storage != null)
         return true;
      return false;
   }

   public StorageDto getStorage(String storageName, DTOConfiguration configuration) {
      Storage storage = this.storageDao.findName(storageName);
      StorageDto storageDto = this.dtoService.convertStorageDto(storage, configuration);
      return storageDto;
   }
}
